
package org.scalabletype.ws;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

import org.jets3t.service.S3ServiceException;
import org.jets3t.service.acl.AccessControlList;
import org.jets3t.service.acl.GroupGrantee;
import org.jets3t.service.acl.Permission;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.model.S3Bucket;
import org.jets3t.service.model.S3Object;
import org.jets3t.service.security.AWSCredentials;

public class Copier {
	private static RestS3Service s3;

	public static void copyStreams(InputStream iStr, OutputStream oStr) throws IOException {
		byte [] buf = new byte[64*1024];	// 64k i/o buffer
		int count = iStr.read(buf);
		while (count != -1) {
			if (count > 0) {
				oStr.write(buf, 0, count);
			}
			count = iStr.read(buf);
		}
		oStr.flush();
		oStr.close();
		iStr.close();
	}

	/**
	 * Needs to be called with AWS credentials before S3 copy methods will work.
	 */
	public static void initS3(String accessId, String secretKey) throws S3ServiceException {
		s3 = new RestS3Service(new AWSCredentials(accessId, secretKey));
	}

	/**
	 * Copies data to an S3 object. If length is != -1, it will be used to set content length, which
	 * allows the data to be streamed instead of buffered in memory.
	 */
	public static void copyToS3(InputStream iStr, long length,
							S3Bucket bucket, String key, String contentType) throws IOException, S3ServiceException {
		if (s3 == null) throw new IllegalStateException("Must call initS3() first");

		S3Object obj = new S3Object(bucket, key);
		AccessControlList bucketAcl = s3.getBucketAcl(bucket);
		bucketAcl.grantPermission(GroupGrantee.ALL_USERS, Permission.PERMISSION_READ);
		obj.setAcl(bucketAcl);
		
		if (length != -1) {
			obj.setContentLength(length);
		}
		if (contentType != null && !contentType.equals("")) {
			obj.setContentType(contentType);
		}
		obj.setDataInputStream(iStr);
		s3.putObject(bucket, obj);
	}

	/**
	 * Copies an object in S3 to an output stream
	 */
	public static S3Object copyFromS3(S3Bucket bucket, String key, OutputStream oStr) throws IOException, S3ServiceException {
		S3Object obj = s3.getObject(bucket, key);
		InputStream iStr = obj.getDataInputStream();
		copyStreams(iStr, oStr);
		return obj;
	}
}
